#ifndef DATATYPE_H
#define DATATYPE_H

#include <opencv2/opencv.hpp>
#include "easylogging++.h"

namespace hnurm {
    // 工作模式
    enum class WorkMode : int {
        auto_shoot = 0, // 英雄、步兵
        auto_sbuff = 1, // 步兵
        auto_bbuff = 2, // 步兵
    };

    // 自己的颜色
    enum class SelfColor : int {
        color_none = 0,
        red = 1,
        blue = 2,
    };

    // 子弹速度
    enum class BulletSpeed : int {
        bulle_speed_none = 0,
        hero10 = 10,
        hero16 = 16,
        infantry15 = 15,
        infantry18 = 18,
        infantry30 = 30 // 炮塔拥有相同的子弹速度
    };

    // 目标状态
    enum class TargetState : int {
        lost_target = 0,
        converging = 1,
        fire = 2,
    };

    // 目标类型
    enum class TargetType : int {
        none = 0,
        hero = 1,
        engineer = 2,
        infantry3 = 3,
        infantry4 = 4,
        infantry5 = 5,
        outpost = 6,
        guard = 7,
        base = 8,
    };

    /**
     * @brief 相机输出，传递给detector进行识别
     */
    struct ImgInfo {
        ImgInfo() = default;
        explicit ImgInfo(cv::Mat &raw_img)
        {
            time_stamp = std::chrono::steady_clock::now();
            img = raw_img.clone();
        }
        cv::Mat img;
        std::chrono::steady_clock::time_point time_stamp;
    };

    /**
     * @brief 由Processor输出的目标信息，传递给Compensator进行补偿计算
     */
    struct TargetInfo {
        TargetInfo() = default;

        TargetState state; // 目标状态
        TargetType type; // 目标类型

        float x{}, y{}, z{}; // 目标的坐标
        float vx{}, vy{}, vz{}; // 目标的速度
        float w_yaw{}, yaw{}; // 目标的角速度和期望的偏航角
        float radius_1{}, radius_2{}; // 目标的半径
        float dz{}; // 目标与玩家之间的距离
    };

    /**
     * @brief 由Compensator输出的补偿后的目标信息，传递给serial进行发送
     */
    struct VisionSendData : public el::Loggable {
        VisionSendData() = default;
        VisionSendData(TargetState state_, TargetType type_, float pitch_, float yaw_)
            : state(state_)
              , type(type_)
              , pitch(pitch_)
              , yaw(yaw_)
        {
        }

        TargetState state; // 目标状态
        TargetType type; // 目标类型

        float pitch ; // 期望的俯仰角，以浮点数形式存储
        float yaw ; // 期望的偏航角，以浮点数形式存储

        virtual void log(el::base::type::ostream_t &os) const {
            os << "pitch: " << pitch << "yaw: " << yaw << "target state" << (int)state;
        }
    };

    /**
     * @brief 由serial接收到的数据，传递给Processor用于计算装甲板的位姿
     */
    struct VisionRecvData : public el::Loggable {
        VisionRecvData() = default;
        VisionRecvData(SelfColor self_color_, WorkMode mode_, BulletSpeed speed_, float pitch_, float yaw_, float roll_)
            : self_color(self_color_)
              , mode(mode_)
              , speed(speed_)
              , pitch(pitch_)
              , yaw(yaw_)
              , roll(roll_)
        {
        }

        SelfColor self_color; // 自己的颜色，以标志寄存器的形式存储，低4位为低8位，高4位为高8位
        WorkMode mode; // 工作模式，以标志寄存器的形式存储，高4位为低8位，低4位为高8位
        BulletSpeed speed; // 子弹速度，以标志寄存器的形式存储，高4位为高8位，低4位为低8位

        float pitch; // 俯仰角
        float yaw; // 偏航角
        float roll; // 翻滚角

        // 重载<<运算符
        virtual void log(el::base::type::ostream_t &os) const {
            os << "self_color: " << static_cast<int>(self_color) << " mode: " << static_cast<int>(mode) << " speed: " << static_cast<int>(speed) << " pitch: " << pitch << " yaw: " << yaw << " roll: " << roll;
        }
        void init(){
            this->self_color = SelfColor::red;
            this->mode = WorkMode::auto_shoot;
            this->speed = BulletSpeed::infantry18;
            this->pitch = 0;
            this->yaw = 0;
            this->roll = 0;
        }
    };

    enum class ArmorsNum { NORMAL_4 = 4, BALANCE_2 = 2, OUTPOST_3 = 3 };

};// namespace hnurm

#endif// !DATATYPE_H
